home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
ddjgrep.zip
/
GREP.C
< prev
next >
Wrap
Text File
|
1987-11-04
|
9KB
|
332 lines
/*---------------------------------------------------------------------------
* GREP.C a generalized regular expression parser
*
*
* Copyright (c) 1984 Allen Holub
* Copyright (c) 1984 Software Engineering Consultants
* P.O. Box 5679
* Berkeley, CA. 94705
*
* All rights reserved.
*
* This program may be copied for personal, non-commmercial use
* only, provided that this copyright notice is included in all
* copies and that this program is not modified in any way.
* Copying for any other use without previously obtaining the
* written permission of the author is prohibited.
*
*---------------------------------------------------------------------------
*/
/*
* The algorithm used here is essentially the algorithm in
* Software Tools in Pascal (pp 145f.). Though the routines have
* been changed somewhat to put them into good 'C'.
*
* This program is a healthy subset of the UNIX program of the same
* name. The differences are as follows:
*
* - the -s, -x, and -b options are not supported.
* - the meta-characters ()+? are not supported.
*
* usage is:
* grep [-vclnhyef] [expression] files ...
*
*/
#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include <string.h>
#include "tools.h"
#define MAXLINE 128 /* Maximum size of an input line */
#define MAX_EXPR 64 /* Maximum number of regular expressions
* seperated by newlines or | allowed
*/
/* The following global flags are true if a switch was set
* on the command line, false otherwise.
*/
int vflag, yflag, cflag, lflag, nflag, hflag, fflag;
main(argc,argv)
int argc;
char **argv;
{
int i, j, linenum, count;
int line[MAXLINE];
int numfiles;
FILE *stream;
int exprc;
TOKEN *exprv[MAX_EXPR];
i = 1;
if (argc < 2)
abort(pr_usage(1));
if (*argv[i] == '-') /* command line switches ? */
{
expand_sw (argv[i++]);
if ( i == argc )
abort(pr_usage(1));
}
/* Pattern string */
if ((exprc = get_expr(exprv, MAX_EXPR, &argv[i++])) == 0)
abort (pr_usage(2));
numfiles = argc - i; /* number of files left to process */
fprintf(stderr," \n"); /* opening message */
do
{
if (numfiles)
{
stream = fopen(argv[i],"r");
if (stream == NULL)
{
fprintf(stderr,"Can't open %s\n", argv[i]);
continue;
}
}
else
stream = stdin;
count = 0;
linenum = 1;
while (fgets(line, MAXLINE, stream))
{
if (yflag) /* MSC routine instead of */
strupr(line); /* stoupper in tools.c */
for (j = exprc; --j >= 0;)
{
if (matchs(line,exprv[j]))
{
count++;
pr_match(linenum,line,argv[i],1,numfiles);
}
else pr_match(linenum,line,argv[i],0,numfiles);
linenum++;
}
if (lflag && count) break;
}
pr_count(numfiles,argv[i],count);
fclose(stream);
} while (++i < argc);
abort();
}
/* ----------------------------------------------------------------------- */
pr_count (fcount,fname,count)
int fcount, count;
char *fname;
{
if (!cflag)
return;
if (fcount > 1)
printf("%-12s: ",fname);
printf("%d\n", count);
}
/* ----------------------------------------------------------------------- */
pr_match (linenum, line, fname, match, numfiles)
int linenum, match, numfiles;
char *line, *fname;
{
char buf[80];
if (cflag)
return;
if ((vflag && !match) || (!vflag && match))
{
if (!hflag && ((numfiles > 1) || lflag))
printf("%s%s",fname,lflag ? "\n" : ":" );
if (nflag)
printf("%03d:",linenum);
if (!lflag)
printf("%s",line);
}
}
/* ----------------------------------------------------------------------- */
pr_usage (num)
int num;
{
#ifdef DEBUG
fprintf(stderr,"%d ", num);
#endif
fprintf(stderr,"usage: grep [-cefhlnvy] [expression] <files...>\n");
}
/* ----------------------------------------------------------------------- */
abort()
{
exit();
}
/* ----------------------------------------------------------------------- */
expand_sw(str)
char *str;
{
vflag = 0;
cflag = 0;
lflag = 0;
nflag = 0;
hflag = 0;
fflag = 0;
yflag = 0;
while (*str)
{
switch (toupper(*str))
{
case '-':
case 'E':
break;
case 'C':
cflag = 1;
break;
case 'F':
fflag = 1;
break;
case 'H':
hflag = 1;
break;
case 'L':
lflag = 1;
break;
case 'N':
nflag = 1;
break;
case 'V':
vflag = 1;
break;
case 'Y':
yflag = 1;
break;
default:
pr_usage(3);
abort();
break;
}
str++;
}
}
/* ----------------------------------------------------------------------- */
int do_or( lp, expr, max )
char *lp;
TOKEN **expr;
int max;
{
int found;
TOKEN *pat;
char *op;
found = 0;
/*
* Extract regular expressions seperated by OR_SYM's from
* lp and put them into expr. Extract only up to max
* expressions. If yflag is true map string to uppercase first
*/
if (yflag)
strupr(lp);
while (op = in_string(OR_SYM, lp))
{
if (found <= max && (pat = makepat(lp,OR_SYM)))
{
*expr++ = pat;
found++;
}
lp = ++op;
if (pat == 0)
goto fatal_err;
}
if (found <= max && (pat = makepat(lp,OR_SYM)))
{
found++;
*expr = pat;
}
if (pat == 0)
{
fatal_err:
printf("Illegal expression\n");
exit();
}
return (found);
}
/* ----------------------------------------------------------------------- */
get_expr (expr, max, defexpr)
TOKEN *expr[];
int max;
char **defexpr;
{
FILE *stream;
int count;
char line[MAXLINE];
#ifdef DEBUG
int i;
#endif
/* Get regular expressions seperated by | or newlines either
* out of a file or off the command line depending on whether
* the -f flag is set. The expressions are converted into
* p